using System;
using System.Collections;
using System.Data.Linq.Mapping;
using System.Runtime.Serialization;
using System.Transactions;
using Portal.Core;
using Portal.Core.Binding.FormBuilder;
using Portal.Core.Helper;
using System.Linq;

namespace Portal.Data.Entity
{
    [Table(Name = "dbo.WebpartPage"), Serializable, DataContractAttribute]
    public class WebpartPage : BaseObject
    {
        #region Ctor
        public WebpartPage()
        {
            PageType = (int)ObjectWebPartPageType.WebPartPageType.Normal;
        }
        #endregion

        #region Properties
        public int ID { get { return WebpartPage_ID; } set { WebpartPage_ID = value; } }

        [SkipBinding]
        [ColumnAttribute(Name = "WebpartPage_ID", IsPrimaryKey = true, IsDbGenerated = true)]
        public int WebpartPage_ID { get; set; }

        [ColumnAttribute(Name = "Name")]
        public string Name { get; set; }

        [ColumnAttribute(Name = "Title")]
        public string Title { get; set; }

        private int _layoutID;
        [ColumnAttribute(Name = "Layout_ID"),
        Lookup(DataSource = "ListAll", DisplayField = "Name", Type = typeof(Layout))]
        public int Layout_ID
        {
            get { return _layoutID; }
            set
            {
                _layoutID = value;
                ChangeLayout(value);
            }
        }

        [ColumnAttribute(Name = "PageType"),
        Lookup(DataSource = "ListAll", DisplayField = "Name", Type = typeof(ObjectWebPartPageType))]
        public int PageType { get; set; }


        #endregion

        #region Methods
        public static WebpartPage FindByPrimaryKey(object objectid)
        {
            return FindByPrimaryKey<WebpartPage>(objectid);
        }
        public static WebpartPage FindByPrimaryKeyRecache(object objectid)
        {
            return FindByPrimaryKey<WebpartPage>(objectid, true);
        }
        public Layout Layout()
        {
            return Entity.Layout.FindByPrimaryKey(Layout_ID);
        }
        public static WebpartPage FindByName(string pageName, bool renewCaching = false)
        {
            //getcache  -----------------------
            var parameter = new object[] { typeof(WebpartPage).Name, "FindByName", pageName };
            if (!renewCaching)
            {
                var obj = CacheHelper.Instance.Get(parameter);
                if (obj != null)
                    return (WebpartPage)obj;
            }
            //end get cache -------------------
            WebpartPage result;

            using (var context = new CmsDataContext())
            {
                context.Connection.Open();
                result = context.WebpartPages.SingleOrDefault(o => o.Name != null && o.Name.ToLower() == pageName.ToLower());
            }
            CacheHelper.Instance.Set(parameter, result);
            return result;
        }
        public static IList ListNormalPages()
        {
            //getcache  -----------------------
            var parameter = new object[] { typeof(WebpartPage).Name, "ListNormalPages" };
            var obj = CacheHelper.Instance.Get(parameter);
            if (obj != null)
                return (IList)obj;
            //end get cache -------------------

            IList result;

            using (var context = new CmsDataContext())
            {
                context.Connection.Open();
                result =
                    context.WebpartPages.Where(o => o.PageType == (int)ObjectWebPartPageType.WebPartPageType.Normal)
                        .ToList();
            }
            CacheHelper.Instance.Set(parameter, result);
            return result;
        }
        public override void AfterSaveUpdate()
        {
            base.AfterSaveUpdate();
            Recache();
        }
        public override void Delete()
        {
            base.Delete();
            Recache();
        }
        void Recache()
        {
            FindByPrimaryKeyRecache(ID);

            var parameter = new object[] { typeof(WebpartPage).Name, "ListNormalPages" };
            CacheHelper.Instance.Set(parameter, null);
        }
        #endregion Methods

        #region Logic
        /// <summary>
        /// Make a null webpartpage with all info, but not save and null Id
        /// </summary>
        /// <returns></returns>       
        public static WebpartPage CreateNewPage()
        {
            var wpage = new WebpartPage { Layout_ID = Entity.Layout.GetFirst().ID, PageType = (int)ObjectWebPartPageType.WebPartPageType.System };
            wpage.Save();
            return wpage;
        }

        public void ChangeLayout(int layoutId)
        {
            if (Layout_ID == layoutId)
                return;
            var layout = Entity.Layout.FindByPrimaryKey(layoutId);

            Layout_ID = layoutId;
            //modify the webparts collection
            int order = 0;
            IList wps = Webpart.FindByWebpartPage(ID);
            string defaultZone = layout.DefaultZone;
            foreach (Webpart part in wps)
            {
                part.Zone = defaultZone;
                part.WebPartOrder = order++;
                part.Update();
            }

            UpdateWithoutPermission();
        }

        public void ChangeWebpartsOrder(string orderData)
        {
            var zones = orderData.Split(':');
            var wps = Webpart.FindByWebpartPage(ID);

            for (int i = 0; i < zones.Length; i++)
            {
                var zone = zones[i].Substring(0, zones[i].IndexOf("("));
                var data = zones[i].Substring(zone.Length + 1, zones[i].Length - zone.Length - 2);

                if (data.Length == 0)
                {
                    continue;
                }

                var parts = data.Split(',');
                for (int j = 0; j < parts.Length; j++)
                {
                    var partId = Convert.ToInt32(parts[j].Substring(3));
                    foreach (Webpart part in wps)
                    {
                        if (part.ID == partId)
                        {
                            part.Zone = zone;
                            part.WebPartOrder = j;
                            part.Update();
                            break;
                        }
                    }
                }
            }
        }

        #endregion
    }

}
